#include<stdio.h>
#include<stdlib.h>
#include "DoubleLinkList.h"


int InitDLlist(DLlist *list)
{
    list->head = NULL;
    list->tail = NULL;
    list->len = 0;
    return 0;
}


struct Node* CreateDLlistNode(ElementType element)
{
    struct Node*NewNode = (struct Node*)malloc(sizeof(struct Node));
    if(NewNode == NULL)
    {
        printf("CreateDLlistNode malloc error!!!\n");
        return NULL;
    }
    NewNode->data = element;
    NewNode->next = NULL;
    NewNode->prev = NULL;
    return NewNode;
}


void InsertTail(DLlist *list, ElementType element)
{
    struct Node *NewNode = CreateDLlistNode(element);
    if(NewNode == NULL)
    {
        printf("inserttail malloc error\n");
        return;
    }
    if(list->len == 0)
    {
        list->head = NewNode;
        list->tail = NewNode;
        list->len++;
        return;
    }
    list->tail->next = NewNode;
    NewNode->prev = list->tail;
    list->tail = list->tail->next;
    list->len++;
}


void TravelDLlist(DLlist *list,void(*func)(ElementType))
{
    struct Node*TravelPoint = list->head;
    while(TravelPoint != NULL)
    {
        if(func != NULL)
        {
            func(TravelPoint->data);
        }
        //printf("%d  ",TravelPoint->data);
        TravelPoint = TravelPoint->next;
    }
    printf("\n");
}


void InsertHead(DLlist *list, ElementType element)
{

    struct Node *NewNode = CreateDLlistNode(element);
    if(list->len == 0)
    {
        list->head = NewNode;
        list->tail = NewNode;
        list->len++;
        return;
    }
    list->head->prev = NewNode;
    NewNode->next = list->head;
    list->head = list->head->prev;
    list->len++;
}


void FreeDLlist(DLlist *list)
{
    while(list->head !=NULL)
    {
        struct Node *freeNode=list->head;
        list->head=list->head->next;
        free(freeNode);  
    }
    list->head = NULL;
    list->tail = NULL;
    list->len = 0;
}

void InsertIndex(DLlist *list, ElementType element, int index)
{
    if(index < 0|| index >= list->len)
    {
        printf("insertIndex place error!!!\n");
        return;
    }

    if(index == 0)
    {
        InsertHead(list,element);
        return;
    }
    else if(index == list->len-1)
    {
        struct Node*NewNode = CreateDLlistNode(element);
        NewNode->next = list->tail;
        NewNode->prev = list->tail->prev;
        list->tail->prev->next = NewNode;
        list->tail->prev = NewNode;
        list->len++;
        return;
    }
    else
    {
        struct Node *TravelPoint = list->head;
        struct Node *NewNode = CreateDLlistNode(element);
        while(index != 0)
        {
            TravelPoint = TravelPoint->next;
            index--;
        }
        NewNode->next = TravelPoint;
        NewNode->prev = TravelPoint->prev;
        TravelPoint->prev->next = NewNode;
        TravelPoint->prev = NewNode;
        
        list->len++;
    }
}


void RemoveByIndex(DLlist *list, int index)
{
    if(index < 0|| index >= list->len)
    {
        printf("RemoveByIndex place error!!!\n");
        return;
    }

    if(list->len ==0)
    {
        printf("双链表内没有元素\n");
        return;
    }

    if(index == 0)
    {
        if(list->len ==1)
        {
            free(list->head);
            list->head = NULL;
            list->tail = NULL;
            list->len = 0;
            return;
        }
        struct Node*temp = list->head;
        list->head = list->head->next;
        list->head->prev = NULL;
        free(temp);
        list->len--;
    }
    else if(index == list->len-1)
    {
        struct Node*temp = list->tail;
        list->tail = list->tail->prev;
        list->tail->next = NULL;
        free(temp);
        list->len--;
        return;
    }
    else
    {
        struct Node *TravelPoint = list->head;
        while(index > 0)
        {
            index--;
            TravelPoint = TravelPoint->next;
        }
        struct Node *PrevNode=TravelPoint->prev;   //前面的那个指针给到 t的前面那个
        struct Node *NextNode=TravelPoint->next;    //后面的那个指针   给到后面的
        PrevNode->next=TravelPoint->next;           //
        NextNode->prev=TravelPoint->prev;
        free(TravelPoint);
        list->len--;
    }
}

int FindFirstElementIndex(DLlist *list,ElementType element)
{
    struct Node *TravelPoint = list->head;
    int count = 0;
    while(TravelPoint !=NULL)
    {
        if(TravelPoint->data == element)
        {
            return count;
        }
        TravelPoint = TravelPoint->next;
        count++;
    }
    return -1;
}

void RemoveByElement(DLlist *list, ElementType element)
{

    int DeleteIndex = FindFirstElementIndex(list,element);
    while(DeleteIndex != -1)
    {
        RemoveByIndex(list,DeleteIndex);
        DeleteIndex = FindFirstElementIndex(list,element);

    }
}

void SetByIndex(DLlist *list,ElementType element, int index)
{
    if(index < 0|| index >= list->len)
    {
        printf("SetByIndex place error!!!\n");
        return;
    }
    struct Node*TravelPoint = list->head;
    while(index != 0)
    {
        index--;
        TravelPoint = TravelPoint->next;
    }
    TravelPoint->data = element;
}

void SetByElememt(DLlist *list, ElementType OldValue, ElementType NewValue)
{
    int SetIndex = FindFirstElementIndex(list,OldValue);
    while(SetIndex != -1)
    {
        struct Node*TravelPoint = list->head;
        while(SetIndex != 0)
        {
            SetIndex--;
            TravelPoint = TravelPoint->next;
        }
        TravelPoint->data = NewValue;
        SetIndex = FindFirstElementIndex(list,OldValue);
    }
}

struct Node *FindByIndex(DLlist *list, int index)
{
    if(index < 0 || index >= list->len)
    {
        printf("FindByIndex place error!!\n");
        return NULL;
    }
    struct Node*TravelPoint = list->head;
    while(index != 0)
    {
        index--;
        TravelPoint = TravelPoint->next;
    }
    return TravelPoint;
}

int *FindByElement(DLlist *list, ElementType element)
{
    int *ReturnArray = (int *)malloc(sizeof(int )*(list->len+1));
    int count = 0;
    int i = 0;
    struct Node*TravelPoint = list->head;

    // while(TravelPoint != NULL)
    // {
    //     if(TravelPoint->data == element)
    //     {
    //         count++;
    //         ReturnArray[count] = i;
    //     }
    //     i++;
    //     TravelPoint = TravelPoint->next;
    // }
    // ReturnArray[0] = count;

    while(TravelPoint != NULL)
    {
        if(TravelPoint->data == element)
        {
            ReturnArray[count] = i;
            count++;
        }
        i++;
        TravelPoint = TravelPoint->next;
    }
    ReturnArray[count] = -1;
    return ReturnArray;
}

DLlist *FindIntersection(DLlist *list1, DLlist *list2)
{
    struct Node* tra1 = list1->head;
    struct Node* tra2 = list2->head;
    DLlist *list3 = (DLlist*)malloc(sizeof(DLlist));
    if(list3 == NULL)
    {
        printf("FindIntersection malloc error\n");
    }
    InitDLlist(list3);
  
    while(tra1 !=NULL)
    {
        tra2 = list2->head;//warning!!!!!每次都需要重置tra2!!!!
        while(tra2 !=NULL)
        {
            if(tra1->data == tra2->data)
            {
                struct Node* tra3 = list3->head;
                int flag = 0;
            
                while(tra3 != NULL)
                {
                    if(tra3->data == tra2->data)
                    {
                        flag = 1;
                    }
                    tra3 = tra3->next;
                }
                if(flag == 0)
                {
                    InsertTail(list3,tra2->data);
                }
            }
            tra2 = tra2->next;
        }
        tra1 = tra1->next;
    }
    return list3;
}


void LinkListBubbleSort(DLlist *list)
{
    for(int i = 0;i <= list->len-1;i++)
    {
        struct Node*TravelPoint = list->head;
        for(int j = 0;j < list->len-i-1;j++)
        {
            if(TravelPoint->data > TravelPoint->next->data)
            {
                if(TravelPoint == list->head)
                {
                    struct Node *Cur = TravelPoint;
                    struct Node *Next = TravelPoint->next;
                    Cur->next = Next->next;
                    Next->prev = NULL;

                    Next->next->prev = Cur;

                    Cur->prev = Next;
                    Next->next = Cur;

                    TravelPoint = Next;//重要
                    list->head = Next;
                }

                else if(TravelPoint->next == list->tail)
                {
                    struct Node *Cur = TravelPoint;
                    struct Node *Next = TravelPoint->next;

                    Cur->next = NULL;
                    Next->prev = Cur->prev;

                    Cur->prev->next = Next;

                    Cur->prev = Next;
                    Next->next = Cur;

                    list->tail = Cur;
                }
                else
                { 
                    struct Node *Cur = TravelPoint;
                    struct Node *Next = TravelPoint->next;
                    Cur->next = Next->next;
                    Next->prev = Cur->prev;

                    Cur->prev->next = Next;
                    Next->next->prev = Cur;

                    Cur->prev = Next;
                    Next->next = Cur;

                    TravelPoint = Next;//这段代码尤其重要，若没有这段代码急急急！！！！！！！！
                    
                }
            }
            TravelPoint = TravelPoint->next;
        }
    }
}

int GetDLlistLen(DLlist *list)
{

    return list->len;
}
